/*!
 *    This program is free software; you can redistribute it and/or modify
 *    it under the terms of the GNU General Public License as published by
 *    the Free Software Foundation; either version 2 of the License, or
 *    (at your option) any later version.
 *
 *    This program is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU General Public License for more details.
 *
 *    You should have received a copy of the GNU General Public License
 *    along with this program; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 *
 *    Author: flareguner
 *    E-Mail: flareguner@gmail.com
 *    Years: 2010-2010
 */

#include "settings.h"
#include "ui_settings.h"
#include "defines.h"

#include <QtGui/QKeyEvent>
#include <QtCore/QSettings>
#include <QtCore/QDebug>



Settings::Settings(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::Settings)
{
    ui->setupUi(this);

    ui->translation_hotkey_label->hide();
    ui->translation_hotkey_lineEdit->hide();

    ui->translation_hotkey_lineEdit->installEventFilter(this);

    connect(ui->translate_when_comboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(whenTranslationTriggerChanged(int)));
    connect(ui->translation_modifier_comboBox, SIGNAL(currentIndexChanged(const QString&)), this, SLOT(slotModifierChanged(const QString&)));
    connect(this, SIGNAL(accepted()), this, SLOT(saveSettings()));
    connect(this, SIGNAL(accepted()),this,SIGNAL(settingsChanged()));
    loadLanguages();
    readSettings();
}

Settings::~Settings()
{
    saveSettings();
    delete ui;
}

// ---------------------------------------------------------------------------------------------------

bool Settings::getAutoTranslate() const {
    return ui->auto_translate_checkBox->isChecked();
}

bool Settings::getCopyToClipboard() const {
    return ui->copy_text_checkBox->isChecked();
}

bool Settings::getAutoDetectLanguage() const {
    return ui->auto_detect_checkBox->isChecked();
}

bool Settings::getSimplifyResult() const {
    return ui->simplify_result_checkBox->isChecked();
}

// ---------------------------------------------------------------------------------------------------

bool Settings::getShowInTray() const {
    return ui->show_in_tray_checkBox->isChecked();
}

bool Settings::getShowToolbar() const {
    return ui->show_toolbar_checkBox->isChecked();
}

QFont Settings::getFont() {
    return ui->fontComboBox->currentFont();
}

QString Settings::getCurrentLanguage() const {
    //! NOTE: need check qm ext. It may be wrong.
    const int i = ui->language_comboBox->currentIndex();
    return qgt_l10n_dir + QDir::separator() + m_languages_list.at(i);
}



// ---------------------------------------------------------------------------------------------------


Settings::NotificationMode Settings::getNotificationMode() const {
    return (Settings::NotificationMode)
            ui->notification_type_comboBox->currentIndex();
}

Settings::TranslationTrigger Settings::getTranslationTrigger() const {
    return (Settings::TranslationTrigger)
            ui->translate_when_comboBox->currentIndex();
}

QString Settings::getTranslationHotkey() const {
    return ui->translation_hotkey_lineEdit->text();
}

// ---------------------------------------------------------------------------------------------------

bool Settings::getHistoryEnabled() const {
    return ui->enable_history_checkBox->isChecked();
}

bool Settings::getReservationEnabled() const {
    return ui->enable_reservation_checkBox->isChecked();
}

bool Settings::getReservationCaseSensetive() const {
    return ui->case_sensetive_reservaton_checkBox->isChecked();
}

bool Settings::getAutoSpeachEnabled() const {
    return ui->auto_pronounce_checkBox->isChecked();
}


QString Settings::getSpeachCmd() const {
    return ui->pronounce_command_lineEdit->text();
}

// ---------------------------------------------------------------------------------------------------

bool Settings::getProxyEnabled() const {
    return ui->enable_proxy_checkBox->isChecked();
}

QNetworkProxy Settings::getProxy() {
    QNetworkProxy proxy;
    proxy.setType(this->getProxyType());
    proxy.setHostName(ui->proxy_adress_lineEdit->text());
    proxy.setPort(ui->proxy_port_spinBox->value());
    proxy.setUser(ui->proxy_login_llineEdit->text());
    proxy.setPassword(ui->proxy_password_lineEdit->text());

    return proxy;
}

// ---------------------------------------------------------------------------------------------------

void Settings::setAutoTranslateChecked(bool b) {
    ui->auto_translate_checkBox->setChecked(b);
}

void Settings::setScanBufferChecked(bool b) {
    if(b) {
        ui->translate_when_comboBox->setCurrentIndex(Settings::SelectionBuffer);
    } else {
        ui->translate_when_comboBox->setCurrentIndex(Settings::None);
    }
}

void Settings::setAutoDetectChecked(bool b) {
    ui->auto_detect_checkBox->setChecked(b);
}

// ---------------------------------------------------------------------------------------------------


void Settings::changeEvent(QEvent *e) {
    QDialog::changeEvent(e);
    switch (e->type()) {
        case QEvent::LanguageChange:
            ui->retranslateUi(this);
            setTranslationModifier(m_translation_modifier);
            setProxyType(m_proxy_type);
            ui->translate_when_comboBox->setCurrentIndex(m_translation_trigger);
            ui->notification_type_comboBox->setCurrentIndex(m_notification_mode);
            break;
        default:
            break;
    }
}

bool Settings::eventFilter(QObject *obj, QEvent *event) {
    if (event->type() == QEvent::KeyPress)
        {
            QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
            int key = keyEvent->text().length() == 1 ? keyEvent->key() : 0;
            int mod = keyEvent->modifiers() & ~Qt::KeypadModifier;
            ui->translation_hotkey_lineEdit->setText(QKeySequence(key + mod).toString());

    #ifdef QGT_DEBUG
            qDebug() << QKeySequence(key + mod).toString();
            qDebug("Ate key press %d (%#x)", keyEvent->key(), keyEvent->key());
    #endif
            return true;
        }
        else
            return QObject::eventFilter(obj, event);

        return true;
    }
// ---------------------------------------------------------------------------------------------------

void Settings::loadLanguages() {
    QDir dir(qgt_l10n_dir);
    if(!dir.exists()) {
        qWarning() << "Error! Translations directory: "
                      << dir.path() << "does not exists! Can't load translations";
        return;
    } else {
        m_languages_list = dir.entryList(QStringList() << "*.qm");
        for(int i = 0; i < m_languages_list.size(); i++) {
            QString cur_item = m_languages_list.at(i);
            cur_item.remove(".qm");
            ui->language_comboBox->addItem(cur_item);
        }
    }
}

QString Settings::getLanguage() const
{
    return ui->language_comboBox->currentText();
}

// ---------------------------------------------------------------------------------------------------

void Settings::setProxyType(const QNetworkProxy::ProxyType type) {
    switch(type) {
    case QNetworkProxy::Socks5Proxy:
        ui->proxy_type_comboBox->setCurrentIndex(0);
    break;

    case QNetworkProxy::HttpProxy:
        ui->proxy_type_comboBox->setCurrentIndex(1);
    break;

    case QNetworkProxy::HttpCachingProxy:
        ui->proxy_type_comboBox->setCurrentIndex(2);
     break;

    default:
        return;
    }
}

QNetworkProxy::ProxyType Settings::getProxyType() {
    const int index = ui->proxy_type_comboBox->currentIndex();
    QNetworkProxy::ProxyType proxy = QNetworkProxy::HttpProxy;
    switch(index) {
    case 0:
        proxy = QNetworkProxy::Socks5Proxy;
    break;

    case 1:
        proxy = QNetworkProxy::HttpProxy;
    break;

     case 2:
        proxy = QNetworkProxy::HttpCachingProxy;
     break;

    default:
     break;
    }
    return proxy;
}

void Settings::saveSettings() {
    QSettings settings(qgt_org, qgt_appname, this);

    settings.beginGroup("translation");
    settings.setValue("auto_translate", ui->auto_translate_checkBox->isChecked());
    settings.setValue("auto_copy", ui->copy_text_checkBox->isChecked());
    settings.setValue("auto_detect", ui->auto_detect_checkBox->isChecked());
    settings.setValue("simplify_result", ui->simplify_result_checkBox->isChecked());
    settings.endGroup();

    settings.beginGroup("appearance");
    settings.setValue("show_in_tray", ui->show_in_tray_checkBox->isChecked());
    settings.setValue("show_toolbar", ui->show_toolbar_checkBox->isChecked());
    settings.setValue("font", ui->fontComboBox->currentFont());
    settings.setValue("language", ui->language_comboBox->currentIndex());
    settings.endGroup();

    settings.beginGroup("notifications");
    settings.setValue("notification_mode", ui->notification_type_comboBox->currentIndex());
    settings.setValue("translation_trigger", ui->translate_when_comboBox->currentIndex());
    settings.setValue("translation_hotkey", ui->translation_hotkey_lineEdit->text());
    settings.setValue("translation_modifier", ui->translation_modifier_comboBox->currentText());
    settings.endGroup();

    settings.beginGroup("tools");
    settings.setValue("enable_history", ui->enable_history_checkBox->isChecked());
    settings.setValue("enable_reservation", ui->enable_reservation_checkBox->isChecked());
    settings.setValue("reservation_cs", ui->case_sensetive_reservaton_checkBox->isChecked());
    settings.setValue("auto_speech_text", ui->auto_pronounce_checkBox->isChecked());
    settings.setValue("speech_cmd", ui->pronounce_command_lineEdit->text());
    settings.endGroup();

    settings.beginGroup("proxy");
    settings.setValue("enabled", ui->enable_proxy_checkBox->isChecked());
    settings.setValue("type", this->getProxyType());
    settings.setValue("host", ui->proxy_adress_lineEdit->text());
    settings.setValue("port", ui->proxy_port_spinBox->value());
    settings.setValue("username", ui->proxy_login_llineEdit->text());
    settings.setValue("password", ui->proxy_password_lineEdit->text());
    settings.endGroup();

}

void Settings::readSettings() {
    QSettings settings(qgt_org, qgt_appname, this);
    settings.beginGroup("translation");
    const bool
            auto_translate = settings.value("auto_translate", false).toBool(),
            auto_copy = settings.value("auto_copy", false).toBool(),
            auto_detect = settings.value("auto_detect", false).toBool(),
            simplify_result = settings.value("simplify_result", false).toBool();
      settings.endGroup();

      ui->auto_translate_checkBox->setChecked(auto_translate);
      ui->copy_text_checkBox->setChecked(auto_copy);
      ui->auto_detect_checkBox->setChecked(auto_detect);
      ui->simplify_result_checkBox->setChecked(simplify_result);

      //---------------------------------------------------------------------------------------

      settings.beginGroup("appearance");
      const bool
              show_in_tray = settings.value("show_in_tray", true).toBool(),
              show_toolbar = settings.value("show_toolbar", true).toBool();
      const QFont font = settings.value("font", 0).value<QFont>();
       const int language = settings.value("language", 0).toInt();
       settings.endGroup();

       ui->show_in_tray_checkBox->setChecked(show_in_tray);
       ui->show_toolbar_checkBox->setChecked(show_toolbar);
       ui->fontComboBox->setCurrentFont(font);
       ui->language_comboBox->setCurrentIndex(language);

       //---------------------------------------------------------------------------------------

       settings.beginGroup("notifications");
       m_notification_mode = (NotificationMode)settings.value("notification_mode", ShowToolTip).toInt();
       m_translation_trigger = (TranslationTrigger)settings.value("translation_trigger", None).toInt();
       QString translation_hotkey = settings.value("translation_hotkey", "Ctrl + Shift + T").toString();
       QString translation_modifier = settings.value("translation_modifier", "Alt").toString();
       settings.endGroup();

       ui->notification_type_comboBox->setCurrentIndex(m_notification_mode);
       ui->translate_when_comboBox->setCurrentIndex(m_translation_trigger);
       whenTranslationTriggerChanged(m_translation_trigger);
       ui->translation_hotkey_lineEdit->setText(translation_hotkey);
       slotModifierChanged(translation_modifier);
       setTranslationModifier(m_translation_modifier);

       //---------------------------------------------------------------------------------------

       settings.beginGroup("tools");
       const bool
               enable_history = settings.value("enable_history", true).toBool(),
               enable_reservation = settings.value("enable_reservation", false).toBool(),
               reservation_cs = settings.value("reservation_cs", false).toBool(),
               auto_speech_text = settings.value("auto_speech_text", false).toBool();

       const QString speech_cmd = settings.value("speech_cmd", qgt_default_speechcmd).toString();
       settings.endGroup();

       ui->enable_history_checkBox->setChecked(enable_history);
       ui->enable_reservation_checkBox->setChecked(enable_reservation);
       ui->case_sensetive_reservaton_checkBox->setEnabled(reservation_cs);
       ui->auto_pronounce_checkBox->setChecked(auto_speech_text);

       ui->pronounce_command_lineEdit->setText(speech_cmd);

       //---------------------------------------------------------------------------------------

        settings.beginGroup("proxy");
        const bool enable_proxy = settings.value("enable", false).toBool();
        m_proxy_type =
                (QNetworkProxy::ProxyType) settings.value("type", QNetworkProxy::HttpProxy).toInt();

       const int proxy_port = settings.value("port", 8118).toInt();
        const QString
                proxy_host = settings.value("host", "").toString(),
                proxy_username = settings.value("username", "").toString(),
                proxy_password = settings.value("password", "").toString();

        ui->enable_proxy_checkBox->setChecked(enable_proxy);
        this->setProxyType(m_proxy_type);
        ui->proxy_port_spinBox->setValue(proxy_port);
        ui->proxy_adress_lineEdit->setText(proxy_host);
        ui->proxy_login_llineEdit->setText(proxy_username);
        ui->proxy_password_lineEdit->setText(proxy_password);
}

void Settings::whenTranslationTriggerChanged(int i) {
    ui->translation_hotkey_lineEdit->hide();
    ui->translation_hotkey_label->hide();
    ui->translation_modifier_comboBox->hide();
    ui->translation_modifier_label->hide();
    switch (i) {
        case HotkeyPress:
            ui->translation_hotkey_lineEdit->show();
            ui->translation_hotkey_label->show();
            break;
        case ModifierPress:
            ui->translation_modifier_comboBox->show();
            ui->translation_modifier_label->show();
            break;
    }
    ui->notification_type_comboBox->setEnabled(i != None);
    ui->notification_label->setEnabled(i != None);

//    emit settingsChanged();
}

void Settings::slotModifierChanged(const QString &text) {
    if (text == "Alt")
        m_translation_modifier = Qt::AltModifier;
    else if (text == "Shift")
        m_translation_modifier = Qt::ShiftModifier;
    else if (text == "Control")
        m_translation_modifier = Qt::ControlModifier;
    else if (text == "Win")
        m_translation_modifier = Qt::MetaModifier;
}

void Settings::setTranslationModifier(Qt::KeyboardModifier mod) {
    QString name;
    switch (mod) {
        case Qt::AltModifier:
            name = "Alt";
            break;
        case Qt::ControlModifier:
            name = "Control";
            break;
        case Qt::ShiftModifier:
            name = "Shift";
            break;
        case Qt::MetaModifier:
            name = "Win";
            break;
        default:
            return;
    }
    m_translation_modifier = mod;
    ui->translation_modifier_comboBox->setCurrentIndex(
        ui->translation_modifier_comboBox->findText(name)
    );
}

Qt::KeyboardModifier Settings::getTranslationModifier() const {
    return m_translation_modifier;
}

